﻿using System.Collections.Generic;
using Cms.Application.Admin.Views;
using Cms.Data;
using Cms.Domain;
using Cms.Domain.RepositoryInterfaces;
using iLib.Utils;

namespace Cms.Application.Admin.Presenters
{
    public class EditLocalePresenter : BasePresenter
    {
        private readonly Administrator _administrator;
        private readonly IEditLocaleView _view;

        public EditLocalePresenter(IEditLocaleView view)
            : this(view, new RepositoryFactory())
        {
        }

        public EditLocalePresenter(IEditLocaleView view, IRepositoryFactory repositoryFactory)
            : base(view, repositoryFactory)
        {
            _view = view;
            _administrator = AdministratorRepository.GetAdministrator(_view.AdministratorID);
            if (!_administrator.HasPermission.EditLocale)
                _view.RedirectToPermissionDeniedPage();
        }

        public void Initialize()
        {
            if (_view.LocaleID == -1)
            {
            }
            else
            {
                Locale locale = LocaleRepository.GetLocale(_view.LocaleID);
                _view.UrlCode = locale.UrlCode;
                _view.AliasDomain = locale.AliasDomain;
                _view.CultureCode = locale.CultureCode;
                _view.NameInNativeLanguage = locale.Translations[locale.ID].Name;
                _view.RegionInNativeLanguage = locale.Translations[locale.ID].Region;
                _view.LanguageNameInNativeLanguage = locale.Translations[locale.ID].Language;
            }
            IList<Locale> otherLocales = new List<Locale>();
            foreach (Locale l in _administrator.CurrentSite.Locales)
                if (l.ID != _view.LocaleID)
                    otherLocales.Add(l);
            if (otherLocales.Count > 0)
            {
                _view.SetLocaleTranslations(otherLocales);
            }
        }

        public string GetThisLocaleNameTranslation(int otherLocaleID)
        {
            Locale locale = LocaleRepository.GetLocale(_view.LocaleID);
            if (locale != null && locale.Translations.ContainsKey(otherLocaleID))
                return locale.Translations[otherLocaleID].Name;
            return "";
        }

        public string GetThisLocaleRegionTranslation(int otherLocaleID)
        {
            Locale locale = LocaleRepository.GetLocale(_view.LocaleID);
            if (locale != null && locale.Translations.ContainsKey(otherLocaleID))
                return locale.Translations[otherLocaleID].Region;
            return "";
        }

        public string GetThisLocaleLanguageTranslation(int otherLocaleID)
        {
            Locale locale = LocaleRepository.GetLocale(_view.LocaleID);
            if (locale != null && locale.Translations.ContainsKey(otherLocaleID))
                return locale.Translations[otherLocaleID].Language;
            return "";
        }
        
        public void Save(IDictionary<int, LocaleTranslation> thisLocaleTranslations,
                         IDictionary<int, LocaleTranslation> otherLocaleTranslations)
        {
            if (_view.UrlCode.Trim() == "")
                AddValidationError(GetText(_view, "NoUrlCodeError"));
            else if (!_administrator.CurrentSite.CanLocaleHaveUrlCode(_view.LocaleID, _view.UrlCode))
                AddValidationError(GetText(_view, "UrlCodeCollisionError"));
            if (_view.NameInNativeLanguage == "")
                AddValidationError(GetText(_view, "NoNameInNativeLanguageError"));
            if (_view.RegionInNativeLanguage == "")
                AddValidationError(GetText(_view, "NoRegionInNativeLanguageError"));
            if (_view.LanguageNameInNativeLanguage == "")
                AddValidationError(GetText(_view, "NoLanguageNameInNativeLanguageError"));
            if (!IsValid)
                return;
            Locale locale;
            Locale otherLocale;
            if (_view.LocaleID == -1)
            {
                locale = new Locale();
                locale.Site = _administrator.CurrentSite;
            }
            else
            {
                locale = LocaleRepository.GetLocale(_view.LocaleID);
            }
            locale.UrlCode = _view.UrlCode;
            locale.AliasDomain = Convert.EmptyToNothing(_view.AliasDomain);
            locale.CultureCode = _view.CultureCode;
            LocaleRepository.SaveLocale(locale);
                // Save to obtain an ID, otherwise we can not add the native translation
            if (_view.LocaleID == -1)
                locale.Translations.Add(locale.ID, new LocaleTranslation());
            locale.Translations[locale.ID].Name = _view.NameInNativeLanguage;
            locale.Translations[locale.ID].Region = _view.RegionInNativeLanguage;
            locale.Translations[locale.ID].Language = _view.LanguageNameInNativeLanguage;
            _view.SetLocaleID(locale.ID);
            foreach (var kvp in thisLocaleTranslations)
            {
                if (!locale.Translations.ContainsKey(kvp.Key))
                    locale.Translations.Add(kvp.Key, kvp.Value);
                else
                    locale.Translations[kvp.Key] = kvp.Value;
            }
            foreach (var kvp in otherLocaleTranslations)
            {
                otherLocale = LocaleRepository.GetLocale(kvp.Key);
                if (!otherLocale.Translations.ContainsKey(locale.ID))
                    otherLocale.Translations.Add(locale.ID, kvp.Value);
                else
                    otherLocale.Translations[locale.ID] = kvp.Value;
            }
            SiteRepository.SaveSite(locale.Site);
        }
    }
}